
package com.ifcar.app.util;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.graphics.drawable.Drawable;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.SparseArray;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class ThemeSettingsHelper {
    private static final String TAG = "ThemeSettingsHelper";

    public static final String THEME_DEFAULT = "default_theme";

    public static final String THEME_NIGHT = "night_theme";
    
    public static final String THEME_OLYMPIC = "olympic_theme";
    
    private static final String[] DEFAULT_CONTEXT_THEMES = new String[] {
        THEME_NIGHT, THEME_OLYMPIC
    };

    private static final String[] DEFAULT_CONTEXT_THEMES_PREFIX = new String[] {
        "night_", "olympic_"
    };

    private final SparseArray<ContextInfo> mCallbacks = new SparseArray<ContextInfo>();

    private Context mThemeContext;

    private String mThemePackageName;

    private static WeakReference<ThemeSettingsHelper> sThemeSettingsHelper;

    public static final ThemeSettingsHelper getThemeSettingsHelper(Context context) {
        if (sThemeSettingsHelper == null || sThemeSettingsHelper.get() == null) {
            sThemeSettingsHelper = new WeakReference<ThemeSettingsHelper>(new ThemeSettingsHelper(
                    context));
        }
        return sThemeSettingsHelper.get();
    }

    private ThemeSettingsHelper(Context context) {
        // TODO 这里应该是取得当前主题包名

        SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
        String theme = sp.getString("theme", THEME_DEFAULT);
        initTheme(context, theme);
    }

    private Object getThemeResource(Context context, int id, String retType) {
        Object o = null;
        String theme = getCurrentThemePackage(context);
        if (THEME_DEFAULT.equals(theme)) {
            return getDefaultResourceValue(context, id, retType);
        }
        
        String prefix = getThemePrefix(theme);
        if (!TextUtils.isEmpty(prefix)) {
            try {
                final Resources res = context.getResources();
                final String resName = prefix + res.getResourceEntryName(id);
                final String type = res.getResourceTypeName(id);
                o = getResourceValueByName(mThemeContext, resName, type, retType);
            } catch (NotFoundException e) {
            }
        } else if (!THEME_DEFAULT.equals(theme)) {
            try {
                final Resources res = context.getResources();
                final String resName = context.getResources().getResourceEntryName(id);
                final String type = res.getResourceTypeName(id);
                o = getResourceValueByName(mThemeContext, resName, type, retType);
            } catch (NotFoundException e) {
            }
        }
        if (o == null) {
            o = getDefaultResourceValue(context, id, retType);
        }

        return o;
    }
    
    private String getThemePrefix(String theme) {
        for (int i = DEFAULT_CONTEXT_THEMES.length - 1; i >= 0; i--) {
            if (DEFAULT_CONTEXT_THEMES[i].equals(theme)) {
                return DEFAULT_CONTEXT_THEMES_PREFIX[i];
            }
        }
        return null;
    }

    private Object getResourceValueByName(Context context, String resName, String type, String retType) {
        resName = resName.toLowerCase().trim();
        final Resources res = context.getResources();
        int id = res.getIdentifier(resName, type, context.getPackageName());
        if (id != 0) {
            Object o = getResourceValue(res, id, type, retType);
            return o;
        }
        return null;
    }

    private Object getDefaultResourceValue(Context context, int id, String retType) {
        final Resources res = context.getResources();
        final String resType = res.getResourceTypeName(id);
        return getResourceValue(res, id, resType, retType);
    }

    private Object getResourceValue(Resources res, int id, String resType, String retType) {
        Object o = null;

        if (!TextUtils.isEmpty(retType)) {
            resType = retType;
        }
        if ("drawable".equals(resType)) {
            o = res.getDrawable(id);
        } else if ("color".equals(resType)) {
            o = res.getColorStateList(id);//.getColor(id);
        }
        return o;
    }

    private Context getThemeContext(Context context, String themePackage) {
        mThemePackageName = themePackage;
        if (THEME_DEFAULT.equals(themePackage)) {
            return context.getApplicationContext();
        }
        
        for (String theme : DEFAULT_CONTEXT_THEMES) {
            if (theme.equals(themePackage)) {
                return context.getApplicationContext();
            }
        }

        try {
            return context.createPackageContext(themePackage, Context.CONTEXT_IGNORE_SECURITY
                    | Context.CONTEXT_INCLUDE_CODE);
        } catch (NameNotFoundException e) {
            mThemePackageName = THEME_DEFAULT;
            return context.getApplicationContext();
        }
    }

    public String getCurrentThemePackage(Context context) {
        if (context != null) {
            final int hashCode = context.hashCode();

            ContextInfo info = mCallbacks.get(hashCode);
            if (info != null && !TextUtils.isEmpty(info.mTheme)) {
                return info.mTheme;
            }
        }
        return mThemePackageName;
    }
    
    public boolean isNightTheme(Context context) {
        return THEME_NIGHT.equals(getCurrentThemePackage(context));
    }

    /**
     * 取消主题修改回调
     * 
     * @param context
     * @param callback
     */
    public void unRegisterThemeCallback(ThemeCallback callback) {
        synchronized (mCallbacks) {
            if (callback != null) {
                Context context = callback.getContext();
                if (context == null) {
                    return;
                }
                final int hashCode = context.hashCode();

                ContextInfo info = mCallbacks.get(hashCode);
                if (info == null) {
                    return;
                }

                info.mCallbacks.remove(callback);

                if (info.mCallbacks.size() == 0) {
                    mCallbacks.remove(hashCode);
                }
            }
        }
    }

    /**
     * 注册主题修改回调
     * 
     * @param context
     * @param callback
     */
    public void registerThemeCallback(ThemeCallback callback, String theme) {
        synchronized (mCallbacks) {
            if (callback == null) {
                return;
            }
            Context context = callback.getContext();
            if (context == null) {
                return;
            }
            final int hashCode = context.hashCode();

            ContextInfo info = mCallbacks.get(hashCode);
            if (info == null) {
                info = new ContextInfo();
                info.mTheme = theme;
                mCallbacks.put(hashCode, info);
            } 
            
            if (info.mCallbacks.contains(callback)) {
                return;
            } else {
                info.mCallbacks.add(callback);
            }
            callback.applyTheme();
        }
    }
    
    private class ContextInfo {
        List<ThemeCallback> mCallbacks = new ArrayList<ThemeCallback>();

        String mTheme;
    }

    private void initTheme(Context context, String theme) {
        mThemeContext = getThemeContext(context, theme);
    }

    public void changeTheme(Context context, String newTheme) {
        synchronized (mCallbacks) {
            final String lastTheme = mThemePackageName;

            initTheme(context, newTheme);

            if (!mThemePackageName.equals(lastTheme)) {
                // TODO 保存新主题名
                SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
                sp.edit().putString("theme", mThemePackageName).commit();

                final int size = mCallbacks.size();
                for (int i = 0; i < size; i++) {
                    ContextInfo info = mCallbacks.valueAt(i);
                    if (info != null && TextUtils.isEmpty(info.mTheme)) {
                        for (int j = info.mCallbacks.size() - 1; j >= 0; j--) {
                            info.mCallbacks.get(j).applyTheme();
                        }
                    }
                }
            }
        }
    }

    public interface ThemeCallback {
        public void applyTheme();
        public Context getContext();
    }

    /**
     * 获取图片
     * 
     * @param context
     * @param resID
     * @return
     */
    public Drawable getThemeDrawable(Context context, int resID) {
        return (Drawable) getThemeResource(context, resID, "drawable");
    }

    /**
     * 获取颜色
     * 
     * @param context
     * @param resID
     * @return
     */
    public ColorStateList getThemeColor(Context context, int resID) {
        return (ColorStateList) getThemeResource(context, resID, null);
    }

    /**
     * 设置Window背景图片
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setWindowBackgroud(Activity activity, int resID) {
        activity.getWindow().setBackgroundDrawable(getThemeDrawable(activity, resID));
    }

    /**
     * 设置背景图片
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setViewBackgroud(Context context, View view, int resID) {
        view.setBackgroundDrawable(getThemeDrawable(context, resID));
    }

    /**
     * 设置背景图片
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setViewBackgroud(Activity activity, int viewid, int resID) {
        View view = activity.findViewById(viewid);
        if (view != null) {
            setViewBackgroud(activity, view, resID);
        }
    }

    /**
     * 设置背景颜色
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setViewBackgroudColor(Context context, View view, int resID) {
        //view.setBackgroundDrawable(getThemeDrawable(context, resID));
      view.setBackgroundColor(getThemeColor(context, resID).getDefaultColor());
    }

    /**
     * 设置背景颜色
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setViewBackgroudColor(Activity activity, int viewid, int resID) {
        View view = activity.findViewById(viewid);
        if (view != null) {
            setViewBackgroudColor(activity, view, resID);
        }
    }

    /**
     * 设置图片
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setImageViewSrc(Context context, ImageView view, int resID) {

      view.setImageDrawable(getThemeDrawable(context, resID));

    }

    /**
     * 设置图片
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setImageViewSrc(Activity activity, int viewid, int resID) {
        ImageView view = (ImageView) activity.findViewById(viewid);
        if (view != null) {
            setImageViewSrc(activity, view, resID);
        }
    }

    /**
     * 设置ListView Selector
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setListViewSelector(Context context, ListView view, int resID) {
        view.setSelector(getThemeDrawable(context, resID));
    }

    /**
     * 设置ListView Selector
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setListViewSelector(Activity activity, int viewid, int resID) {
        ListView view = (ListView) activity.findViewById(viewid);
        if (view != null) {
            setListViewSelector(activity, view, resID);
        }
    }

    /**
     * 设置ListView Divider
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setListViewDivider(Context context, ListView view, int resID) {
        view.setDivider(getThemeDrawable(context, resID));
    }

    /**
     * 设置ListView Divider
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setListViewDivider(Activity activity, int viewid, int resID) {
        ListView view = (ListView) activity.findViewById(viewid);
        if (view != null) {
            setListViewDivider(activity, view, resID);
        }
    }

    /**
     * 设置字体颜色
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setTextViewColor(Context context, TextView view, int resID) {
        view.setTextColor(getThemeColor(context, resID));
    }

    /**
     * 设置字体颜色
     * 
     * @param context
     * @param view
     * @param resID
     */
    public void setTextViewColor(Activity activity, int viewid, int resID) {
        TextView view = (TextView) activity.findViewById(viewid);
        if (view != null) {
            setTextViewColor(activity, view, resID);
        }
    }
}
